package com_.dxy_test_.itext;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com_.dxy_test_.drawseal.DrawSealTest;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

/**
 * @Description 测试生成PDF文档
 * @Author dangxianyue
 * @Date 2024/3/29 16:03
 */
public class TestJava2PDF {

    private static final String DEST = "C:\\Users\\Alex\\Desktop\\out.pdf";

    public static void main(String[] args) throws Exception {
        // test1();
        test2();

    }

    /**
     * 无模板生成
     * 参考：https://blog.csdn.net/double_hll123/article/details/127421837
     * @throws DocumentException
     * @throws IOException
     */
    private static void test1() throws DocumentException, IOException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));
        document.open();
        // 设置中文字体，不然中文会显式不了
        BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font font = new Font(bf, 12);

        // 添加一个段落
        final Paragraph paragraph = new Paragraph("hello world 王小明", font);
        document.add(paragraph);

        // 添加一个3列表格
        final PdfPTable table = new PdfPTable(3);
        table.addCell("Name");
        table.addCell("Quantity");
        table.addCell("Price");

        table.addCell("iPhone 11");
        table.addCell("1");
        table.addCell("$10");

        table.addCell(new Paragraph("小米 13", font));
        table.addCell("3");
        table.addCell(new Paragraph("￥20", font));
        document.add(table);

        document.close();
        writer.close();
    }

    /**
     * 由模板生成
     * 如何做PDF模板？
     * 1. 先通过WPS做一个Word文件，然后输出未PDF
     * 2. 在Adobe Acrobat DC软件打开PDF，填单表单文本域，表单项名称就是填充数据的key
     * 3. 参考资料：https://blog.csdn.net/TOP__ONE/article/details/65442390
     * @throws IOException
     * @throws DocumentException
     */
    private static void test2() throws IOException, DocumentException {
        // 获取模板文件
        final ClassLoader classLoader = TestJava2PDF.class.getClassLoader();
        final URL resource = classLoader.getResource("template/pdf_template_demo.pdf");
        final String templatePath = resource.getPath();
        System.out.println("templatePath: " + templatePath);

        final FileOutputStream out = new FileOutputStream(DEST);// 输出流
        final PdfReader reader = new PdfReader(templatePath);// 读取pdf模板
        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
        final PdfStamper stamper = new PdfStamper(reader, bos);
        AcroFields form = stamper.getAcroFields();

        // 设置中文字体并嵌入到PDF文件中，需要itext-asian包
        BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
        fontList.add(bf);
        form.setSubstitutionFonts(fontList);

        // 填充字段
        form.setField("name", "王小明");
        form.setField("number", "A001");
        form.setField("score", "92.5");
        form.setField("birthday", "2021-10-13");
        // 文字过多需要设置文本域的多行属性为true
        // 同时要主要设置文本域表单的大小，人为保证字数不要超出表单的范围
        form.setField("address", "广东省广州市天河区长兴街道岑村南街深巷10号401室");

        // 插入图片
        final String imagePath = classLoader.getResource("image/stamp1.png").getPath();
        System.out.println("imagePath: " + imagePath);
        final String imageKey = "image";// 图片表单域名称
        int pageNo = form.getFieldPositions(imageKey).get(0).page;
        Rectangle signRect = form.getFieldPositions(imageKey).get(0).position;

        // 表单域大小，需在Adobe Acrobat DC中设置好
        float x = signRect.getLeft();
        float y = signRect.getBottom();

        // 插入本地图片
        // Image image = Image.getInstance(imagePath);

        // 插入生成的图
        final BufferedImage bufferedImage = DrawSealTest.buildSealImage("2024-03-31");
        final byte[] imageByte = bufferedImageToByteArray(bufferedImage);
        Image image = Image.getInstance(imageByte);
        // 获取操作的页面
        PdfContentByte under = stamper.getOverContent(pageNo);
        // 根据域的大小缩放图片
        image.scaleToFit(signRect.getWidth(), signRect.getHeight());
        // 添加图片
        image.setAbsolutePosition(x, y);
        under.addImage(image);

        stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑，一定要设为true
        stamper.close();

        Document doc = new Document();
        PdfCopy copy = new PdfCopy(doc, out);
        doc.open();
        PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
        copy.addPage(importPage);
        doc.close();


    }

    /**
     * 把Buffered对象转为byte数组
     * @param image
     * @return
     * @throws IOException
     */
    private static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException {
        try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
            //bufferedImage转为byte数组
            ImageIO.write(image, "jpg", outStream);
            return outStream.toByteArray();
        }
    }
}
